import ProjectModel from "../schema/project";
import { Request, Response } from "express";
import Types from "../typings";

// Common 类的实例
import Common from "./common";
const CommonIns = new Common(ProjectModel);

// 响应类型实例
import ResType from "./resType";
const ResTypeIns = new ResType();

class Project {
  constructor() {}

  // 递归查询项目信息
  static recursion = async (list: Types.Project.ProjectType[]) => {
    for (let i = 0, len = list.length; i < len; i++) {
      const parentId = list[i].id;
      const data = await CommonIns.Find({
        parentId,
      });
      list[i].children = (await Project.recursion(data)) || [];
    }
    return list;
  };

  async list(req: Request, res: Response) {
    try {
      const creatorId = CommonIns.getLoginUserId(
        req as Types.Express.ConvertRequest
      );

      const { code = "" } = req.query;

      const query: Partial<Types.Project.ProjectType> = {
        creatorId,
        parentId: "",
      };

      code && query.code;

      let rootLevel: Types.Project.ProjectType[] = await CommonIns.Find(query);

      rootLevel = (await Project.recursion(rootLevel)) || [];

      ResTypeIns.Success(res, rootLevel);
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  async check(req: Request, res: Response) {
    try {
      let { id } = req.query;

      if (!id) {
        ResTypeIns.paramsWrong(res);
      } else {
        const projects: Types.Project.ProjectType[] = await CommonIns.Find({
          id,
        });

        if (!projects.length) {
          ResTypeIns.isNotExist(res);
        } else {
          ResTypeIns.Success(res, projects[0]);
        }
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  async add(req: Request, res: Response) {
    try {
      const creatorId = CommonIns.getLoginUserId(
        req as Types.Express.ConvertRequest
      );

      const { parentId, name, code } = req.body;

      const projects: Types.Project.ProjectType[] = await CommonIns.Find({
        code,
      });

      if (projects.length) {
        ResTypeIns.isExist(res);
      } else {
        const parent: Types.Project.ProjectType[] = await CommonIns.Find({
          id: parentId,
        });

        await CommonIns.SaveOne({
          parentId,
          parentName: parent[0]?.name,
          name,
          code,
          creatorId,
          createdTime: Date.now(),
          updatedTime: Date.now(),
        });

        ResTypeIns.Success(res);
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  async update(req: Request, res: Response) {
    try {
      const { id, parentId, name } = <Partial<Types.Project.ProjectType>>(
        req.body
      );
      if (!id) {
        ResTypeIns.paramsWrong(res);
      } else {
        const updateContent = {
          parentId,
          name,
          updatedTime: Date.now(),
        };

        await CommonIns.UpdateOne({ id }, updateContent);
        ResTypeIns.Success(res);
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }

  async remove(req: Request, res: Response) {
    try {
      let { id } = req.query;

      if (!id) {
        ResTypeIns.paramsWrong(res);
      } else {
        const childs: Types.Project.ProjectType[] = await CommonIns.Find({
          parentId: id,
        });

        if (childs.length) {
          res.send({
            code: 500,
            data: null,
            msg: "请先删除所有的子节点",
          });
        } else {
          await CommonIns.RemoveOne({ id });

          ResTypeIns.Success(res);
        }
      }
    } catch (err) {
      ResTypeIns.Database(res, err);
    }
  }
}

export default Project;
